#pragma once

#include <QLabel>
#include <QPoint>
#include <QTimer>
#include <QWidget>

#include "widgets.h"

#define QBTIP_MAX_ITEM_COUNT 20

namespace qb {
class QBTipLabel : public QLabel {
  struct QBTipItem {
    QBTipItem() : bCustom(false), font(nullptr) {}
    QColor clrNormal;
    QFont* font;
    bool bCustom;
  };

  Q_OBJECT
 public:
  QBTipLabel(const QString& text, const QPoint& pos, QWidget* w,
             int msecDisplayTime, bool html = false);
  ~QBTipLabel();
  static QBTipLabel* instance;

  void updateSize(const QPoint& pos);
  bool eventFilter(QObject*, QEvent*) override;

  QBasicTimer hideTimer, expireTimer;

  bool fadingOut;

  void reuseTip(const QString& text, int msecDisplayTime, const QPoint& pos);
  void hideTip();
  void hideTipImmediately();
  void setTipRect(QWidget* w, const QRect& r);
  void restartExpireTimer(int msecDisplayTime);
  bool tipChanged(const QPoint& pos, const QString& text, QObject* o);
  void placeTip(const QPoint& pos, QWidget* w);
  void clearCustomItem();
  void setCustomItem(int row, int col, QColor clrNormal, QFont* font);
  void setBorderColor(QColor clrBorder);
  void setHtml(bool v);

  static int getTipScreen(const QPoint& pos, QWidget* w);

 protected:
  void timerEvent(QTimerEvent* e) override;
  void paintEvent(QPaintEvent* e) override;
  void mouseMoveEvent(QMouseEvent* e) override;
  void resizeEvent(QResizeEvent* e) override;

 private:
  QWidget* widget;
  QRect rect;
  QColor border;
  QBTipItem tipItems[QBTIP_MAX_ITEM_COUNT][QBTIP_MAX_ITEM_COUNT];
  bool m_html = false;
};

struct S_WIDGETS_EXPORT QBTipCustomItem {
  int row;
  int col;
  QColor clrNormal;
  QFont* font = nullptr;
};

class S_WIDGETS_EXPORT QBTips {
  QBTips() = delete;

 public:
  static void showText(const QPoint& pos, const QString& text,
                       QWidget* w = nullptr,
                       std::vector<QBTipCustomItem>* vctCustomItem = nullptr,
                       bool followMouse = false, bool html = false,
                       int margin = 6, int msecShowTime = -1,
                       QColor border = QColor(94, 94, 94, 255));
  static inline void hideText() { showText(QPoint(), QString()); }
  static void hideTip();

  static bool isVisible();
  static QString text();

  static QPalette palette();
  static void setPalette(const QPalette&);
  static QFont font();
  static void setFont(const QFont&);
};
}  // namespace qb